using System;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace My.IdlConverter.Core
{
    using Parsers;
    using Filters;
    using Cfg;

    class ClassStore
    {
        private static IDictionary<string, StringCollection> _classInterfaceFilesMaps = new Dictionary<string, StringCollection>();

        public static IDictionary<string, StringCollection> ClassInherits
        {
            get
            {
                return _classInterfaceFilesMaps;
            }
        }

        public static string AddInherit(string targetFilePath)
        {
            string classString = null;
            if (!Util.IOHelper.ReadToEnd(targetFilePath, out classString))
            {
                Debug.Assert(false);
                return null;
            }

            AddInherit(targetFilePath, classString);

            IPreprocessor<string> precessor = new ClassPreprocessor(classString);
            classString = precessor.Process();

            return classString;
        }

        public static Class GetClass(string className)
        {
            if (!ClassModifier.IsDOMClassName(className))
            {
                Trace.WriteLine(className+" is not DOM class");
                return null;
            }
            StringCollection interfaceNames = GetBaseInterfaceNames(className);
            if (interfaceNames.Count == 0)
                return null;

            Class retClass = new Class(className);

            string INTERFACE_FOLDER = Configuration.InterfaceFolder;
            IParser parser = new InterfaceParser();

            string nextInterfaceFile = null;
            foreach (string nextInterfaceName in interfaceNames)
            {
                if (IsClass(nextInterfaceName))
                {
                    retClass.BaseInterfaces.Add(GetClass(nextInterfaceName));
                }
                else
                {
                    nextInterfaceFile = Path.Combine(INTERFACE_FOLDER, nextInterfaceName + ".h");
                    Interface interfaceObj = parser.Parse(nextInterfaceFile) as Interface;
                    if (interfaceObj != null)
                        retClass.BaseInterfaces.Add(interfaceObj);
                }
            }

            return retClass;
        }

        private static void AddInherit(string targetFilePath, string classString)
        {
            IPreprocessor<string> precessor = new ClassPreprocessor(classString);
            classString = precessor.Process();

            string className = Recognizer.GetDOMClassName(targetFilePath);

            StringCollection baseInterfaceNames = GetBaseInterfaces(classString);
            if (!ClassStore.ClassInherits.ContainsKey(className))
                ClassStore.ClassInherits.Add(className, baseInterfaceNames);
        }

        private static StringCollection GetBaseInterfaceNames(string className)
        {
            if (_classInterfaceFilesMaps.ContainsKey(className))
                return _classInterfaceFilesMaps[className];
            else
            {
                string fileTitle = className.Trim();
                fileTitle = fileTitle.Remove(0, "Cv_".Length);
                string targetClassFilePath = Path.Combine(Configuration.ClassFolder, fileTitle + ".h");
                string classString = null;
                if (!Util.IOHelper.ReadToEnd(targetClassFilePath, out classString))
                {
                    targetClassFilePath = Path.Combine(Configuration.InterfaceFolder,fileTitle+".h");
                    if (Util.IOHelper.ReadToEnd(targetClassFilePath,out classString))
                    {
                       // Debug.Assert(false);
                    }
                }
                AddInherit(targetClassFilePath, classString);

                return _classInterfaceFilesMaps[className];
            }
        }

        private static bool IsClass(string name)
        {
            return name.StartsWith("Cv_DOM");
        }

        private static StringCollection GetBaseInterfaces(string classString)
        {
            MatchCollection matchCol = Regex.Matches(classString,ClassParser.VTL_INTERFACE_ENTRY_REGEX);
            string classOrInterfaceName = null;

            StringCollection baseInterfaces = new StringCollection();

            string vtl_interface_entry = null;
            foreach (Match nextMatch in matchCol)
            {
                vtl_interface_entry = nextMatch.Value;

                if (ClassModifier.ExtraceInterfaceName(vtl_interface_entry, out classOrInterfaceName))
                {
                    if (InterfaceModifier.IsDOMInterfaceName(classOrInterfaceName))
                    {
                        baseInterfaces.Add(classOrInterfaceName);
                    }
                }
                else if (ClassModifier.ExtraceClassName(vtl_interface_entry, out classOrInterfaceName))
                {
                    if (ClassModifier.IsDOMClassName(classOrInterfaceName))
                    {
                        baseInterfaces.Add(classOrInterfaceName);
                    }
                }
                else
                {
                    Trace.WriteLine("Class should Not be DOM class : " + nextMatch.Value);
                }
            }

            return baseInterfaces;
        }
    }
}
